import subprocess
import time
import os
import datetime

import emoji
from plyer import notification

import uiautomation as auto

def openWechat():
    subprocess.Popen("D:\WeChat\WeChat.exe")

def getHuihuaUser(wx,listenUser):
    openWechat()
    huihuaUser = None
    huihuaList = wx.ListControl(Name="会话")
    for o in huihuaList.GetChildren():
        if (o.ControlType == auto.ControlType.ListItemControl and (
                o.Name == listenUser or o.Name == listenUser + "已置顶")):
            huihuaUser = o
    return huihuaUser

def getMyRuntimeId(item):
    return ''.join([str(i) for i in item.GetRuntimeId()])

def run():
    # 打开微信
    openWechat()

    # 获取登录用户
    wx = auto.WindowControl(searchDepth=1,Name="微信",ClassName="WeChatMainWndForPC")
    loginUser = wx.ToolBarControl(Name="导航").GetChildren()[0].Name
    print("当前登录用户: {}".format(loginUser))

    # 切换到聊天列表
    wx.ToolBarControl(Name="导航").ButtonControl(Name="聊天").Click()

    # 初始化监听对象
    listenUsers = [
        "文件传输助手"
    ]
    chatDict = dict()
    for listenUser in listenUsers:
        chatDict[listenUser] = dict()
        chatDict[listenUser]["name"] = listenUser
        chatDict[listenUser]["runtime_ids"] = []

    # 打开会话窗口
    for listenUser in listenUsers:
        # 判断会话窗口是否已经打开
        huihuaWindowExists = auto.WindowControl(Name=listenUser).Exists(maxSearchSeconds=0.8)
        if not huihuaWindowExists:
            huihuaUser = getHuihuaUser(wx, listenUser)
            if not huihuaUser:
                # 输出搜索内容
                search = wx.EditControl(Name="搜索")
                search.Click()
                # 分析字符中如果含有emoji标签,加上\uFE0E样式
                searchListenUser = ""
                for s in listenUser:
                    if emoji.is_emoji(s):
                        searchListenUser += s + u'\uFE0E'
                    else:
                        searchListenUser += s
                # 设置粘贴板
                auto.SetClipboardText(searchListenUser)
                # 发送复制指令
                search.SendKeys('{Ctrl}v')
                # 搜索
                wx.ListControl(Name="@str:IDS_FAV_SEARCH_RESULT:3780").ListItemControl(Name=listenUser).Click()
                huihuaUser = getHuihuaUser(wx, listenUser)
            # 双击打开会话窗口
            huihuaUser.DoubleClick()

    # 监听聊天数据
    while True:
        msgDict = dict()
        for who in chatDict:
            msgs = []
            chat = chatDict[who]
            # 首次填充消息id
            listUserWindow = auto.WindowControl(Name=who)
            msgList = listUserWindow.ListControl(Name="消息")
            if not chat["runtime_ids"]:
                for o in msgList.GetChildren():
                    chat["runtime_ids"].append(getMyRuntimeId(o))
                chatDict[who] = chat
            # 取最新消息
            newMsgItems = []
            # 若当前消息的runtimeId不在chatDict的runtime_ids数组里,则输出消息数据并保存当前runtimeId到chatDict的runtime_ids数组
            for o in msgList.GetChildren():
                if getMyRuntimeId(o) not in chat["runtime_ids"]:
                    newMsgItems.append(o)
            if newMsgItems:
                for newMsgItem in newMsgItems:
                    chat["runtime_ids"].append( getMyRuntimeId(newMsgItem) )
                    chatDict[who] = chat
                    # 消息内容
                    content = newMsgItem.Name
                    nickName = ""
                    if newMsgItem.GetChildren():
                        for o in newMsgItem.GetChildren()[0].GetChildren():
                            if o.ControlType == auto.ControlType.ButtonControl:
                                nickName = o.Name
                        excludeContents = ["以下为新消息", "查看更多消息"]
                        if nickName and content and content in excludeContents and nickName==content:
                            continue
                        if not nickName and content and content in excludeContents:
                            continue
                        if nickName:
                            if nickName == loginUser:
                                msg = ["self", content, getMyRuntimeId(newMsgItem)]
                            else:
                                msg = [nickName, content, getMyRuntimeId(newMsgItem)]
                        else:
                            msg = ["SYS", content, getMyRuntimeId(newMsgItem)]
                        msgs.append(msg)
                        msgDict[who] = msgs
                        # 发送提醒
                        if nickName and nickName !=loginUser:
                            notification.notify(
                                title="提醒",
                                message=",".join(msg),
                                app_name="我的应用",
                                timeout=10,
                                ticker="快捷提示"
                            )
                        # 分析消息内容
                        if content == "[图片]":
                            listUserWindow.SwitchToThisWindow()
                            # 触发图片点击,打开图片查看窗口
                            imgButtonControl = newMsgItem.ButtonControl(Name="")
                            imgButtonControl.Click()
                            # 触发保存流程
                            picViewWindow = auto.WindowControl(Name="图片查看")
                            picViewWindow.ButtonControl(Name="另存为...").Click()
                            # 保存
                            savePath = os.path.join(os.getcwd(), "微信文件", "微信图片_{}.jpg".format(
                                datetime.datetime.now().strftime('%Y%m%d%H%M%S%f')))
                            if not os.path.exists(os.path.split(savePath)[0]):
                                os.mkdir(os.path.split(savePath)[0])
                            saveWindow = picViewWindow.WindowControl(Name="另存为...")
                            saveWindow.EditControl(Name="文件名:").SendKeys(savePath)
                            time.sleep(1)
                            saveWindow.ButtonControl(Name="保存(S)").Click()
                            # 判断是否已存在,存在则覆盖
                            exists = saveWindow.PaneControl(Name="确认另存为").Exists(1)
                            if exists:
                                saveWindow.PaneControl(Name="确认另存为").ButtonControl(Name="是(Y)").Click()
                            saveContent = "图片保存路径:{}".format(savePath)
                            print(saveContent)
                            # 发送提醒
                            notification.notify(
                                title="提醒",
                                message=saveContent,
                                app_name="我的应用",
                                timeout=10,
                                ticker="快捷提示"
                            )
                            # 关闭图片查看窗口
                            picViewWindow.ButtonControl(Name="关闭").Click()
        print(msgDict)
        time.sleep(5)

if __name__=="__main__":
    run()